﻿using System.Configuration;
using System.IO;
using System.Xml.Serialization;
using Amazon.S3;
using Amazon.S3.Model;

namespace PCC.AWS
{
    public class FileStorage : IFileStorage
    {
        private readonly AmazonS3Client _s3Client;
        private readonly string _key;
        private readonly string _secret;
        private readonly string _bucket;
        private readonly string _baseUrl;
        private const string XMLContentType = "text/xml";

        public FileStorage()
        {
            _key = ConfigurationManager.AppSettings["AWSKey"];
            _secret = ConfigurationManager.AppSettings["AWSSecret"];
            _bucket = ConfigurationManager.AppSettings["AWSBucket"];
            _baseUrl = ConfigurationManager.AppSettings["AWSS3Base"];
            _s3Client = new AmazonS3Client(_key, _secret);
        }

        public string Upload(string filename, Stream input, string contentType)
        {
            PutObjectRequest request = GetRequest(contentType, filename);
            request.InputStream = input;
            _s3Client.PutObject(request);
            return GetFullS3Url(filename);
        }

        public string Upload(string filename, byte[] data, string contentType)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.Write(data, 0, data.Length);
                return Upload(filename, ms, contentType);
            }
        }

        public string Upload(string filename, string data, string contentType)
        {
            var request = GetRequest(contentType, filename);
            request.ContentBody = data;
            _s3Client.PutObject(request);
            return GetFullS3Url(filename);
        }

        public string Upload<T>(string filename, T data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                var xml = new XmlSerializer(typeof(T));
                xml.Serialize(ms, data);
                return Upload(filename, ms.ToArray(), XMLContentType);
            }
        }

        public T Download<T>(string filename)
        {
            GetObjectRequest request = new GetObjectRequest()
                .WithBucketName(_bucket)
                .WithKey(filename);
            GetObjectResponse response = _s3Client.GetObject(request);

            var xml = new XmlSerializer(typeof(T));
            return (T)xml.Deserialize(response.ResponseStream);
        }

        private PutObjectRequest GetRequest(string contentType, string filename)
        {
            return new PutObjectRequest()
                .WithBucketName(_bucket)
                .WithContentType(contentType)
                .WithKey(filename);
        }

        private string GetFullS3Url(string filename)
        {
            return string.Format("{0}/{1}", _baseUrl, filename);
        }
    }
}
